home *** CD-ROM | disk | FTP | other *** search
- From: Juergen Lock <nox@jelal.north.de>
- From: Juergen Lock <nox@jelal.north.de>
- Subject: try this out...
- Date: Sat, 18 Sep 93 18:55:54 CES
- From: Juergen Lock <nox@jelal.north.de>
- Message-Id: <9309181656.AA00236@jelal.north.de>
-
- hi!
-
- this started as an idea last week, and now...
-
- (please don't pass this around until i know its reasonably stable.
- works for me, i'm using it right now but as usual that doesn't say
- much... i would also like some comment from Eric because it contains
- parts which are his code. thanx...)
-
- # This is a shell archive.
- # Remove everything above and including the cut line.
- # Then run the rest of the file through sh.
- #----cut here-----cut here-----cut here-----cut here----#
- #!/bin/sh
- # shar: Shell Archiver
- # Run the following text with /bin/sh to create:
- # README
- # vcon.c
- # vtdev.c
- # vcon.h
- # vtdev.h
- # Makefile
- # This archive created: 18-September-1993 18:13:06 CES
- # By: nox@jelal.north.de (Juergen Lock)
- cat << \SHAR_EOF > README
- From: Juergen Lock <nox@jelal.north.de>
-
- here is something you've all been waiting for... virtual terminals
- for MiNT :-) now you can...
-
- use up to 10 shells/whatever without magnifying glasses or 19" screens
- run GEM on the console, top on vt01 and gdb' a GEM program from vt02...
- send MiNTs debug output to another terminal than the debugged program
- when some stupid program hangs and MiNT is still alive just switch to
- another terminal and send the thing a signal. (ever heared of vp/ix?
- oops, wrong CPU...)
- temporarily suspend GEM while you need your cycles for something more
- important than polling the mouse ;) i.e. just send SIGSTOP and SIGCONT
- later. (now if MiNT only had swapping...)
- show people that its not MiNT that is slow, only GEM :-) also the
- screen writing code in vtdev.c is mostly based on MiNTs fasttext.c
- (including hardware scrolling for all terminals except the console)
- so i guess output is faster than any GEM window writing could ever get.
-
- how to use:
-
- this should run ok on any machine where MiNTs /dev/fasttext worked
- (worked because you won't need it anymore then) and where
- Setscreen (-1, base, -1) allows setting the displayed screen
- independent of the one GEM (or VDI actually) writes to. if it doesn't
- work for you tell me, or better yet just fix it and send diffs. :-)
-
- with init simply put something like this into your rc.local:
-
- --------cut------
- if [ -f /usr/etc/vcon ]; then
- echo "starting virtual consoles"
- vcon
- mv /dev/console /dev/con00
- mv /dev/vt00 /dev/console
- rm /etc/ttytab
- ln /etc/ttytab.vt /etc/ttytab
- else
- rm /etc/ttytab
- ln /etc/ttytab.con /etc/ttytab
- fi
- -------------
-
- (the mv.s are for programs that open /dev/console so they get the
- new one... writing to the old one should be no problem, but reading is.)
-
- ttytab.vt has entries for console and vt01..09 (of course not all of
- them need be `on' :-), ttytab.con only has the original console. and
- remember GEM can only run on console...
-
- without init put something like this in mint.cnf (and then set CON to
- the new console). of course without init you'll have to do its job
- yourself, i.e. put gettys or shells etc. on the new terminals `by hand'.
-
- you can also add this to termcap:
-
- stv52|MiNT virtual console:\
- :ti=\Ev\Ee\Ez_:am:te=\Ev\Et@\Ee\Ez_:\
- :al=\EL:bs:cd=\EJ:ce=\EK:cl=\EE:cm=\EY%+ %+ :co#80:\
- :dl=\EM:do=\EB:ho=\EH:\
- :li#25:se=\Eq:so=\Ep:up=\EA:nd=\EC:\
- :rs=\Ez_\Eb@\EcA:\
- :ue=\EzH:us=\EyH:md=\E(:me=\E)\Eq:\
- :ms:pt:\
- :sr=2*\EI:\
- :sf=2*^J:\
- :kl=#K:kr=#M:ku=#H:kd=#P:\
- :kI=#R:kh=#G:kH=#O:kP=#I:kN=#Q:\
- :k0=#D:k1=#;:k2=#<:k3=#=:\
- :k4=#>:k5=#?:k6=#@:k7=#A:k8=#B:k9=#C:\
- :s0=#]:s1=#T:s2=#U:s3=#V:\
- :s4=#W:s5=#X:s6=#Y:s7=#Z:s8=#[:s9=#\\:\
- :vi=\Ef:ve=\Et@\Ee:vs=\Et :\
- :cQ=\Et@:cV=\Et :
-
- (and add a new console type to gettytab that sets tt i.e. TERM =stv52),
- then less etc know how to underline text wich i also have added.
- btw the k.. and s.. with # are scancodes for elvis, others might want
- escape sequences...
-
- oh and to switch between terminals just hit alt-fkey... f10 is the
- console. when it `bing's at you that means the terminal has no screen
- memory because no process has it open... with init you can turn it on in
- ttytab and send init SIGHUP. and when it `bing's at you while you type
- that means the terminals `keyboard queue' is full... to empty it hit
- alt-undo. (if its empty alt-undo gets passed thru, so programs can
- still use it.)
-
- ok, happy testing...
- Juergen
- SHAR_EOF
- cat << \SHAR_EOF > vcon.c
- /*
- * virtual terminals for MiNT, 1st try
- *
- * vt01..9 are fast hardware-scrolling text-terminals, vt00 is the
- * original console and can still be used for GEM. (i hope :)
- * to change terminals hit alt-function key (f1 == vt01... f10 == vt00),
- * alt-undo kills a terminals key buffer. (useful when your auto-repeat
- * is faster than a program processes input, etc)
- *
- * how it works: each open vt.. device has a screen buffer and input pipe.
- * keyboard input is read and scanned for control and alt-f keys by a
- * daemon (in main()) that changes screens and sends input and signals to
- * the correct processes.
- * vt00 uses the original screen memory, vt01..9 share one bigger screen
- * for display and store the other screens contents in line buffers
- * so they can be `hardware-scrolled' without taking extra memory.
- * (just move pointers around.. line offsets actually) closed `stored'
- * terminals don't take up screen memory.
- *
- * send bugs & comments to: Juergen Lock <nox@jelal.north.de>
- */
-
- #include <osbind.h>
- #include <sysvars.h>
- #undef flock
- #undef _sysbase
- #define _sysbase (* ((OSHEADER **) 0x4f2))
- #include <mintbind.h>
- #include <setjmp.h>
- #include <support.h>
- #include <signal.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "vcon.h"
- #include "vtdev.h"
-
- /* kernel information */
- struct kerinfo *kernel;
-
- struct dev_descr devinfo[] = {
- &vcon_device, 0, O_TTY, ttys+0, 0L, 0L, 0L, 0L, /* vt00 (console) */
- &vcon_device, 1, O_TTY, ttys+1, 0L, 0L, 0L, 0L, /* vt01 */
- &vcon_device, 2, O_TTY, ttys+2, 0L, 0L, 0L, 0L, /* vt02 */
- &vcon_device, 3, O_TTY, ttys+3, 0L, 0L, 0L, 0L, /* vt03 */
- &vcon_device, 4, O_TTY, ttys+4, 0L, 0L, 0L, 0L, /* vt04 */
- &vcon_device, 5, O_TTY, ttys+5, 0L, 0L, 0L, 0L, /* vt05 */
- &vcon_device, 6, O_TTY, ttys+6, 0L, 0L, 0L, 0L, /* vt06 */
- &vcon_device, 7, O_TTY, ttys+7, 0L, 0L, 0L, 0L, /* vt07 */
- &vcon_device, 8, O_TTY, ttys+8, 0L, 0L, 0L, 0L, /* vt08 */
- &vcon_device, 9, O_TTY, ttys+9, 0L, 0L, 0L, 0L /* vt09 */
- };
-
- #define MAX_VT ((sizeof devinfo)/sizeof (struct dev_descr))
-
- struct tty ttys[MAX_VT];
-
- struct sgttyb con;
- int conflags;
- short hardscroll = -1;
- struct tchars con_tc, tc0;
- struct ltchars con_ltc, ltc0;
-
- int pfd[MAX_VT], cfd, vcurrent, pgrp;
- short leaving;
-
- static int xcurrent;
-
- void xflash();
-
- long xsetcurrent()
- {
- return setcurrent (xcurrent);
- }
-
- void xwakeselect()
- {
- WAKESELECT(ttys[vcurrent].rsel);
- }
-
- void con_raw()
- {
- Fcntl(0, &con, TIOCGETP);
- Fcntl(0, &con_tc, TIOCGETC);
- Fcntl(0, &con_ltc, TIOCGLTC);
- conflags = con.sg_flags;
- con.sg_flags &= ~(CBREAK|ECHO|TOSTOP);
- Fcntl(0, &con, TIOCSETN);
- Fcntl(0, &tc0, TIOCSETC);
- Fcntl(0, <c0, TIOCSLTC);
- }
-
- void con_sane()
- {
- if (cfd) {
- /* try to uninstall gracefully... */
- int i, opencnt = 0;
- char *vt00name=ttyname(cfd), *oldcname=ttyname(0), *s;
- long vpgrp;
-
- /* /dev/vt00 might be renamed /dev/console... */
- if (vt00name && (s = strrchr (vt00name, '/')) &&
- !strcmp (s, "/console"))
- rename (vt00name, "u:/dev/vt00");
- /* move original console device in place */
- if (oldcname && (s = strrchr (oldcname, '/')) &&
- strcmp (s, "/console"))
- rename (oldcname, "u:/dev/console");
-
- /* tell processes their tty is going away */
- leaving = 1;
- for (i = 0; i < MAX_VT; ++i) {
- if (ttys[i].use_cnt > !i) {
- ++opencnt;
- if ((vpgrp = ttys[vcurrent].pgrp))
- killpg(vpgrp, SIGHUP);
- }
- }
- /* wait until all the devices are closed... */
- while (opencnt) {
- opencnt = 0;
- /* sleep(1); (save space...) */
- (void) Fselect (1000, 0l, 0l, 0l);
- for (i = 0; i < MAX_VT; ++i)
- if (ttys[i].use_cnt > !i)
- ++opencnt;
- }
- xcurrent = 0;
- Supexec (xsetcurrent);
- Fclose (cfd);
-
- /* ..and remove them */
- for (i = 0; i < MAX_VT; ++i) {
- char name[] = "u:\\dev\\vt00";
-
- name[sizeof "u:\\dev\\vt0"-1] = i+'0';
- Fdelete (name);
- }
- #if 1
- vpgrp = 0;
- Fcntl(0, &vpgrp, TIOCSPGRP);
- #endif
- }
- con.sg_flags=conflags; /* restore console */
- Fcntl(0, &con, TIOCSETN);
- Fcntl(0, &con_tc, TIOCSETC);
- Fcntl(0, &con_ltc, TIOCSLTC);
- }
-
- /* handle fatal signals */
- void trap(sig)
- int sig;
- {
- con_sane();
- signal(sig, SIG_DFL);
- /* die! */
- kill(getpid(), sig);
- }
-
- /* pass signal to process on the pty */
- void trap_int(sig)
- int sig;
- {
- int vpgrp;
-
- /* see who is on the tty and if its a different process group... */
- if (ttys[vcurrent].use_cnt && (vpgrp = ttys[vcurrent].pgrp) != pgrp) {
- /* if yes, pass the signal */
- signal(sig, SIG_IGN);
- killpg(vpgrp, sig);
- signal(sig, trap_int);
- }
- }
-
- static OSHEADER *syshdr;
-
- void getsyshd()
- {
- syshdr = _sysbase->os_beg;
- }
-
- /* get a (TOS version dependant) pointer to the current shift/alt
- keyboard status
- */
- char *getpkbshift()
- {
- /* get OS header */
- (void) Supexec(getsyshd);
- /* TOS 1.(0)2 or newer has it in the header */
- if (syshdr->os_version > 0x100)
- return syshdr->pkbshift;
- else
- /* TOS 1.0 */
- return (char *) 0x0e1bL;
- }
-
- /* on MiNT fork and vfork both block until the child does either exec or
- dies. only tfork doesn't block but it works like a subroutine call... */
- static jmp_buf tforkj;
-
- static int in_tfork(arg)
- int arg;
- {
- /* wait for parent to die before we can longjmp back */
- while (getppid () > 1)
- (void) Fselect (1000, 0l, 0l, 0l);
- longjmp (tforkj, 1);
- /*NOTREACHED*/
- }
-
- /* queue up characters for a terminal */
-
- void csend (vcurrent, fd, cbuf, bufp)
- int vcurrent, fd;
- long *cbuf, *bufp;
- {
- long bytes = (char *)bufp - (char *)cbuf;
-
- if (bytes) {
- /* pipe full? */
- if (Foutstat (fd) < bytes)
- /* bing... */
- Fputchar (0, 07l, 0);
- else {
- /* else send buffer */
- Fwrite (fd, bytes, cbuf);
- /* if someone select()ed this terminal wake 'em up */
- if (ttys[vcurrent].rsel)
- Supexec (xwakeselect);
- }
- }
- }
-
- /*
- * main: initialization stuff, and a daemon that handles input from
- * the physical console
- */
-
- main()
- {
- int i;
- long pgrp;
- char *s;
- volatile char *pkbshift = getpkbshift();
- long cbuf[0x80], *bufp;
-
- /* sanity check */
- if (!(s = ttyname (0)) || (!(s = strrchr (s, '/'))) ||
- strcmp (s, "/console")) {
- Cconws ("Sorry this is fast not `clean' software :) console only...\r\n");
- exit (1);
- }
-
- /* stdin RAW, catch signals... */
- pgrp = getpid(/*0*/);
- Fcntl(0, &con, TIOCGETP);
- Fcntl(0, &con_tc, TIOCGETC);
- Fcntl(0, &con_ltc, TIOCGLTC);
- conflags = con.sg_flags;
- signal(SIGHUP, trap);
- signal(SIGTERM, trap);
- signal(SIGINT, trap_int);
- signal(SIGQUIT, trap_int);
- con_raw();
-
- for (i = 0; i < MAX_VT; ++i) {
- char name[] = "u:\\pipe\\q$vt00";
-
- name[sizeof "u:\\pipe\\q$vt0"-1] = i+'0';
- if ((pfd[i] = Fcreate (name, FA_RDONLY|FA_CHANGED)) < 0) {
- con_sane();
- Cconws ("Huh? unable to create pipe...\r\n");
- exit (1);
- }
- /* hmm. tfork goes thru Pexec, and Pexec looks at
- close-on-exec flags...
- */
- Fcntl (pfd[i], 0, F_SETFD);
- }
- for (i = 0; i < MAX_VT; ++i) {
- char name[] = "u:\\dev\\vt00";
-
- name[sizeof "u:\\dev\\vt0"-1] = i+'0';
- kernel = (struct kerinfo *)Dcntl(DEV_INSTALL, name, devinfo+i);
- if (!kernel || ((long)kernel) == -32) {
- con_sane();
- Cconws ("Uh :( unable to install vt device(s)!\r\n");
- exit (1);
- }
- }
-
- if ((cfd = Fopen ("u:\\dev\\vt00", O_RDWR)) < 0) {
- con_sane();
- Cconws ("Help!! Fopen new console device failed.\r\n");
- exit (1);
- }
- Fcntl (cfd, 0, F_SETFD);
- #if 0
- /* better put this in rc.local... (or mint.cnf) */
- Frename (0, "u:\\dev\\console", "u:\\dev\\con00");
- Frename (0, "u:\\dev\\vt00", "u:\\dev\\console");
- #endif
-
- /* hack until MiNT gets a real nonblocking fork... one day :)
- */
- if (!setjmp(tforkj) && tfork (in_tfork, 0l) >= 0)
- _exit (0);
-
- /* ok parent continues, has to close old /dev/console now... */
- pgrp = setpgrp(/*pgrp, pgrp*/);
- Fcntl(0, &pgrp, TIOCSPGRP);
- Fcntl(0, (void *) O_NDELAY, F_SETFL);
- /* hmm part 2: tfork resets signals too... */
- signal(SIGHUP, trap);
- signal(SIGTERM, trap);
- signal(SIGINT, trap_int);
- signal(SIGQUIT, trap_int);
-
- /* now the daemon part
- poll keyboard, switch between terminals, start/stop output,
- send signals, flash cursor...
- */
- bufp = cbuf;
- for (;;) {
- char name[] = "u:\\pipe\\q$vt00";
- int fd = pfd[vcurrent], scan;
- char cshift;
- unsigned long l;
-
- /* empty buffer if full */
- if (bufp == cbuf+sizeof cbuf) {
- csend (vcurrent, fd, cbuf, bufp);
- bufp = cbuf;
- }
- cshift = *pkbshift;
- /* if nothing to read empty buffer and do a select */
- if ((l=Fgetchar (0, 0)) == MiNTEOF) {
- csend (vcurrent, fd, cbuf, bufp);
- bufp = cbuf;
- for (;;) {
- int ctimeout = 0;
- long rfd = 1;
-
- if (vcurrent) {
- SCREEN *v = v0x+vcurrent-1;
- ctimeout = 500;
-
- if ((CURS_FLASH|CURS_ON) ==
- (v->flags & (CURS_FLASH|CURS_ON)))
- ctimeout = v->period*20;
- }
- if (Fselect (ctimeout, &rfd, (long *)0, (long *)0)) {
- /* show cursor if flashing and off */
- if (vcurrent) {
- SCREEN *v = v0x+vcurrent-1;
-
- if ((CURS_FLASH|CURS_ON) ==
- (v->flags & (CURS_FLASH|CURS_ON|CURS_FSTATE)))
- Supexec (xflash);
- }
- /* then go read whats there */
- break;
- }
- /* select timed out, flash cursor & try again */
- Supexec (xflash);
- }
- continue;
- }
- if ((cshift & ~0x10) == 8) switch (scan=(char) (l>>16)) {
- int xfd; /* ALT-something */
-
- case 0x61: /* ALT-UNDO: flush pipe if !empty */
- name[sizeof "u:\\pipe\\q$vt0"-1] = vcurrent+'0';
- if ((xfd = Fopen (name, O_RDONLY)) >= 0
- && Finstat (xfd) > 0) {
- Fcntl (xfd, (char *) 0, TIOCFLUSH);
- Fclose (xfd);
- bufp = cbuf;
- continue;
- } else if (bufp > cbuf) {
- bufp = cbuf;
- continue;
- }
- break;
- case 0x3b: /* ALT-F1: vt01 */
- case 0x3c: /* ALT-F2: vt02 */
- case 0x3d: /* . */
- case 0x3e: /* . */
- case 0x3f: /* . */
- case 0x40:
- case 0x41:
- case 0x42:
- case 0x43: /* ALT-F9: vt09 */
- scan += 10;
- /*FALLTHRU*/
- case 0x44: /* ALT-F10: vt00 */
- if ((scan -= 0x44) < MAX_VT) {
- csend (vcurrent, fd, cbuf, bufp);
- bufp = cbuf;
- xcurrent = scan;
- if (Supexec (xsetcurrent))
- Fputchar (0, 07l, 0);
- continue;
- }
- break;
- } else if ((ttys[vcurrent].state & TS_COOKED) ||
- (cshift & 0xc) == 0xc) {
- char ch = (char) l;
- int sig = 0;
-
- if (!ch)
- ; /* do nothing */
- else if (ch == ttys[vcurrent].tc.t_intrc)
- sig = SIGINT;
- else if (ch == ttys[vcurrent].tc.t_quitc)
- sig = SIGQUIT;
- else if (ch == ttys[vcurrent].ltc.t_suspc)
- sig = SIGTSTP;
- else if (ch == ttys[vcurrent].tc.t_stopc) {
- ttys[vcurrent].state |= TS_HOLD;
- continue;
- }
- else if (ch == ttys[vcurrent].tc.t_startc) {
- ttys[vcurrent].state &= ~TS_HOLD;
- continue;
- }
- if (sig) {
- ttys[vcurrent].state &= ~TS_HOLD;
- if (!(ttys[vcurrent].sg.sg_flags & T_NOFLSH)) {
- Fcntl (fd, (char *) 0, TIOCFLUSH);
- bufp = cbuf;
- }
- killpg (ttys[vcurrent].pgrp, sig);
- continue;
- }
- else if (ttys[vcurrent].state & TS_HOLD) {
- continue;
- }
- }
- *bufp++ = l;
- }
- }
-
- SHAR_EOF
- cat << \SHAR_EOF > vtdev.c
- /*
- virtual terminal devices, based on MiNTs fasttext.c, that is...
-
- Copyright 1991,1992 Eric R. Smith.
- Copyright 1992,1993 Atari Corporation.
- All rights reserved.
- */
-
- #include <stddef.h>
- #include <errno.h>
- #include <osbind.h>
- #include "vcon.h"
- #include "vtdev.h"
-
- #ifdef __GNUC__
- #define INLINE inline
- #define ITYPE long /* gcc's optimizer likes 32 bit integers */
- #else
- #define INLINE
- #define ITYPE int
- #endif
-
- #define CONDEV (2)
-
- SCREEN *v00, v0x[N_VT-1];
-
- static void paint P_((SCREEN *, int, char *)),
- paint8c P_((SCREEN *, int, char *)),
- paint816m P_((SCREEN *, int, char *));
-
- INLINE static void curs_off P_((SCREEN *)), curs_on P_((SCREEN *));
- INLINE static void flash P_((SCREEN *));
- static void normal_putch P_((SCREEN *, int));
- static void escy_putch P_((SCREEN *, int));
- static void quote_putch P_((SCREEN *, int));
-
- static char *chartab[256];
-
- static int fgmask[MAX_PLANES], bgmask[MAX_PLANES];
-
- static long scrnsize;
-
- short hardscroll;
- static char *hardbase, *oldbase;
-
- #define base (*((char **)0x44eL))
- #define V_BASE(v) ((v) == v00 ? base : (v)->v.t.vbase)
- #define V_LINE(v, lx4) ((v) == v00 ? (base + *(long *)(rowoff+(lx4))) : \
- ((v)->v.t.vbase + *(long *)((v)->v.t.rowlist+(lx4))))
- #define V_LINEAR_P(v) ((v) == v00 || (v)->v.t.on)
- #define VT_SCREEN(vt) ((vt) ? v0x+(vt)-1 : v00)
- #define escy1 (*((short *)0x4acL))
- #define V_ESCY1(v) ((v) == v00 ? escy1 : (v)->v.t.vescy1)
- #define V_FGMASK(v) ((v) == v00 ? fgmask : (v)->v.t.fgmask)
- #define V_BGMASK(v) ((v) == v00 ? bgmask : (v)->v.t.bgmask)
- #define _hz_200 (*((long *)0x4baL))
-
- static Vfunc v00state;
- #define V_STATE(v) ((v) == v00 ? &v00state : &(v)->v.t.state)
-
- static short hardline;
- static void (*vpaint) P_((SCREEN *, int, char *));
- static char *rowoff;
- static short qfd[N_VT], q_fl[N_VT];
-
- void exchangeb P_((void *, void *, long));
- void init P_((void));
- int setcurrent P_((int));
- void hardware_scroll P_((SCREEN *));
- INLINE static char *PLACE P_((SCREEN *, int, int));
- INLINE static void gotoxy P_((SCREEN *, int, int));
- INLINE static void clrline P_((SCREEN *, int));
- INLINE static void clear P_((SCREEN *));
- INLINE static void clrchars P_((SCREEN *, int, int, int));
- INLINE static void clrfrom P_((SCREEN *, int, int, int, int));
- INLINE static void delete_line P_((SCREEN *, int));
- INLINE static void insert_line P_((SCREEN *, int));
- static void setbgcol P_((SCREEN *, int));
- static void setfgcol P_((SCREEN *, int));
- static void setcurs P_((SCREEN *, int));
- static void putesc P_((SCREEN *, int));
- static void escy1_putch P_((SCREEN *, int));
- #if 0
- INLINE static void put_ch P_((SCREEN *, int));
- #else
- INLINE static void put_ch00 P_((SCREEN *, int));
- INLINE static void put_ch0x P_((SCREEN *, int));
- #endif
-
- /* routines for flashing the cursor for screen v */
- /* flash(v): invert the character currently under the cursor */
-
- INLINE static void
- flash(v)
- SCREEN *v;
- {
- char *place;
- ITYPE i, j, vplanes;
-
- vplanes = v->planes + v->planes;
- place = v->cursaddr;
-
- for (j = v->cheight; j > 0; --j) {
- for (i = 0; i < vplanes; i+=2)
- place[i] = ~place[i];
-
- place += v->planesiz;
- }
- v->curstimer = v->period;
- }
-
- /* actually flash cursor (called from vcon.c) */
-
- void xflash()
- {
- SCREEN *v = v0x+vcurrent-1;
-
- /* vt00's cursor is handled by TOS... */
- if (!vcurrent || v->hidecnt)
- return;
- if ((CURS_FLASH|CURS_ON) == (v->flags & (CURS_FLASH|CURS_ON))) {
- flash(v);
- v->flags ^= CURS_FSTATE;
- }
- }
-
- /* make sure the cursor is off */
-
- INLINE
- static void
- curs_off(v)
- SCREEN *v;
- {
- if (v->flags & CURS_ON) {
- if (v->flags & CURS_FSTATE) {
- flash(v);
- v->flags &= ~CURS_FSTATE;
- }
- }
- }
-
- /* OK, show the cursor again (if appropriate) */
-
- INLINE static void
- curs_on(v)
- SCREEN *v;
- {
- if (v->hidecnt) return;
-
- if (v->flags & CURS_ON) {
- #if 0
- /* if the cursor is flashing, we cheat a little and leave it off
- * to be turned on again (if necessary) by the VBL routine
- */
- if (v->flags & CURS_FLASH) {
- v->curstimer = 2;
- return;
- }
- #endif
- if (!(v->flags & CURS_FSTATE)) {
- /* if you can't see the cursor there's no
- reason to flash it */
- if ((v->flags & CURS_FLASH) &&
- v != v00 && (!vcurrent || !v->v.t.on))
- return;
- v->flags |= CURS_FSTATE;
- flash(v);
- }
- }
- }
-
- #ifdef __GNUC__
- #define lineA0() \
- ({ register char *retvalue __asm__("d0"); \
- __asm__ volatile(" \
- .word 0xa000 " \
- : "=r"(retvalue) \
- : \
- : "d0", "d1", "d2", "a0", "a1", "a2" \
- ); \
- retvalue; \
- })
- #endif
-
- /* init vt0[1-9] SCREEN struct */
-
- void
- init_screen(v, vbase, rowlist, on)
- SCREEN *v;
- char *vbase, *rowlist;
- short on;
- {
- static char initv00[sizeof (SCREEN) - offsetof (SCREEN, cheight)];
-
- if (on)
- memmove (initv00, (char *)&v00->cheight, sizeof (initv00));
- bzero ((char *)v, offsetof (SCREEN, cheight));
- memmove ((char *)&v->cheight, initv00, sizeof (initv00));
-
- v->v.t.vbase = vbase;
- v->v.t.rowlist = rowlist;
- v->v.t.on = on;
- v->v.t.state = normal_putch;
- v->cursaddr = vbase;
- v->cx = 0; v->cy = 0;
- v->flags = CURS_ON|CURS_FLASH|FWRAP;
- setbgcol(v, v->bgcol);
- setfgcol(v, v->fgcol);
- clear(v);
- }
-
- void
- init()
- {
- SCREEN *v;
- int i, j;
- char *data, *foo;
- static char chardata[256*16];
- register int linelen;
-
- foo = lineA0();
- v = v00 = (SCREEN *)(foo - 346);
-
- /* Ehem... The screen might be bigger than 32767 bytes.
- Let's do some casting...
- Erling
- */
- linelen = v->linelen;
- scrnsize = (v->maxy+1)*(long)linelen;
- rowoff = (char *)kmalloc((long)((v->maxy+1) * sizeof(long) * (N_VT-1)));
- if (rowoff == 0) {
- FATAL("Insufficient memory for screen offset table!");
- } else {
- long off, *lptr = (long *)rowoff;
- SCREEN *vp = v0x+1;
-
- for (i=0, off=0; i<=v->maxy; i++) {
- *lptr++ = off;
- off += linelen;
- }
- for (i=0; i<N_VT-1; i++) {
- (vp++)->v.t.rowlist = (char *)lptr;
- lptr += v->maxy+1;
- }
- }
- if (hardscroll == -1) {
- /* request for auto-setting */
- hardscroll = v->maxy+1;
- }
- if (!hardbase) {
- hardbase = (char *)(((long)kcore(SCNSIZE(v)+256L)+255L)
- & 0xffffff00L);
- if (hardbase == 0)
- FATAL("Insufficient memory for second screen buffer!");
- init_screen(v0x, hardbase, rowoff, V_FREE);
- }
- hardline = 0;
- if (v->cheight == 8 && v->planes == 2) {
- foo = &chardata[0];
- vpaint = paint8c;
- for (i = 0; i < 256; i++) {
- chartab[i] = foo;
- data = v->fontdata + i;
- for (j = 0; j < 8; j++) {
- *foo++ = *data;
- data += v->form_width;
- }
- }
- } else if ((v->cheight == 16 || v->cheight == 8) && v->planes == 1) {
- foo = &chardata[0];
- vpaint = paint816m;
- for (i = 0; i < 256; i++) {
- chartab[i] = foo;
- data = v->fontdata + i;
- for (j = 0; j < v->cheight; j++) {
- *foo++ = *data;
- data += v->form_width;
- }
- }
- }
- else
- vpaint = paint;
-
- if (v->hidecnt == 0) {
- /*
- * make sure the cursor is set up correctly and turned on
- */
- (void)Cursconf(0,0); /* turn cursor off */
-
- v->flags &= ~CURS_FSTATE;
-
- /* now turn the cursor on the way we like it */
- v->curstimer = v->period;
- v->hidecnt = 0;
- v->flags |= CURS_ON;
- curs_on(v);
- } else {
- (void)Cursconf(0,0);
- v->flags &= ~CURS_ON;
- v->hidecnt = 1;
- }
-
- /* setup bgmask and fgmask */
- setbgcol(v, v->bgcol);
- setfgcol(v, v->fgcol);
- *V_STATE(v) = normal_putch;
- }
-
- /* deinit, must be called after last close */
-
- void
- deinit()
- {
- kfree (rowoff);
- }
-
- /* exchange memory, assumes pointers word-aligned and bytes
- multiple of sizeof long... (faster implementations welcome :-)
- */
-
- INLINE
- void
- exchangeb(x1, x2, bytes)
- void *x1, *x2;
- long bytes;
- {
- long *p, *q, t;
-
- for (p = x1, q = x2; bytes > 0; bytes -= sizeof (long)) {
- t = *p;
- *p++ = *q;
- *q++ = t;
- }
- }
-
- /*
- * PLACE(v, x, y): the address corresponding to the upper left hand corner of
- * the character at position (x,y) on screen v
- */
- INLINE static
- char *PLACE(v, x, y)
- SCREEN *v;
- int x, y;
- {
- char *place;
- int i, j;
-
- if (V_LINEAR_P(v)) {
- place = V_BASE(v) + x;
- if (y == v->maxy)
- place += scrnsize - v->linelen;
- else if (y) {
- y+=y; /* Make Y into index for longword array. */
- y+=y; /* Two word-size adds are faster than a 2-bit shift. */
- place += *(long *)(rowoff + y);
- }
- } else {
- y+=y; /* Make Y into index for longword array. */
- y+=y; /* Two word-size adds are faster than a 2-bit shift. */
- place = V_LINE(v, y) + x;
- }
- if ((j = v->planes-1)) {
- i = (x & 0xfffe);
- do place += i;
- while (--j);
- }
- return place;
- }
-
- int
- setcurrent(vt)
- int vt;
- {
- static int v0xcurrent = 1;
- SCREEN *v = VT_SCREEN(vt);
-
- /* are we changing to a `stored' screen? */
- if (vt && vt != v0xcurrent) {
- SCREEN *oldv = VT_SCREEN(v0xcurrent);
- char *foo, *vline = oldv->v.t.vbase;
- int i;
-
- if (!v->v.t.vbase)
- /* sorry terminal closed, has no screen memory */
- return 1;
-
- /* exchange screen contents... */
- for (i=0; i<=v->maxy*sizeof (long); i+=sizeof (long)) {
- exchangeb (vline, V_LINE(v, i), v->linelen);
- vline += v->linelen;
- }
- /* and pointers... */
- foo = oldv->v.t.vbase;
- oldv->v.t.vbase = v->v.t.vbase;
- v->v.t.vbase = foo;
- foo = oldv->v.t.rowlist;
- oldv->v.t.rowlist = v->v.t.rowlist;
- v->v.t.rowlist = foo;
-
- /* free screen memory if told so */
- if (oldv->v.t.on == V_FREE) {
- oldv->v.t.on = 0;
- kfree (oldv->v.t.vbase);
- oldv->v.t.vbase = 0;
- } else {
- oldv->v.t.on = 0;
- oldv->cursaddr = PLACE(oldv, oldv->cx, oldv->cy);
- }
- v->v.t.on = V_USED;
- v->cursaddr = PLACE(v, v->cx, v->cy);
- v0xcurrent = vt;
- }
- vcurrent = vt;
- if (vt && (v->flags & CURS_FLASH))
- curs_on(v);
- Setscreen(-1l, V_BASE(v), -1);
- return 0;
- }
-
- /*
- * paint(v, c, place): put character 'c' at position 'place' on screen
- * v. It is assumed that x, y are proper coordinates!
- * Specialized versions (paint8c and paint816m) of this routine follow;
- * they assume 8 line high characters, medium res. and 8 or 16 line/mono,
- * respectively.
- */
-
- static void
- paint(v, c, place)
- SCREEN *v;
- int c;
- char *place;
- {
- char *data, d, doinverse;
- ITYPE j, planecount;
- int vplanes;
- long vform_width, vplanesiz;
- int *fgmaskv = V_FGMASK(v), *bgmaskv = V_BGMASK(v);
-
- vplanes = v->planes;
-
- data = v->fontdata + c;
- doinverse = (v->flags & FINVERSE) ? 0xff : 0;
- vform_width = v->form_width;
- vplanesiz = v->planesiz;
-
- for (j = v->cheight-1; j > 0; --j) {
- d = *data ^ doinverse;
- for (planecount = 0; planecount < vplanes; planecount++)
- place[planecount << 1]
- = ((d & (char) fgmaskv[planecount])
- | (~d & (char) bgmaskv[planecount]));
- place += vplanesiz;
- data += vform_width;
- }
- d = ((v->flags & FUNDERLINE) ? -1 : *data) ^ doinverse;
- for (planecount = 0; planecount < vplanes; planecount++)
- place[planecount << 1]
- = ((d & (char) fgmaskv[planecount])
- | (~d & (char) bgmaskv[planecount]));
- }
-
- static void
- paint8c(v, c, place)
- SCREEN *v;
- int c;
- char *place;
- {
- char *data;
- char d, doinverse, dounderline;
- char bg0, bg1, fg0, fg1;
- long vplanesiz;
- int *m;
-
- data = chartab[c];
-
- doinverse = (v->flags & FINVERSE) ? 0xff : 0;
- dounderline = (v->flags & FUNDERLINE) ? 0xff : 0;
- vplanesiz = v->planesiz;
- m = V_BGMASK(v);
- bg0 = *m++;
- bg1 = *m++;
- m = V_FGMASK(v);
- fg0 = *m++;
- fg1 = *m++;
-
- if (!doinverse && !bg0 && !bg1 && fg0 && fg1) {
- /* line 1 */
- d = *data++;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 2 */
- d = *data++;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 3 */
- d = *data++;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 4 */
- d = *data++;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 5 */
- d = *data++;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 6 */
- d = *data++;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 7 */
- d = *data++;
- *place = d;
- place[2] = d;
- place += vplanesiz;
-
- /* line 8 */
- d = *data | dounderline;
- *place = d;
- place[2] = d;
- } else {
- /* line 1 */
- d = *data++ ^ doinverse;
- *place = ((d & fg0) | (~d & bg0));
- place[2] = ((d & fg1) | (~d & bg1));
- place += vplanesiz;
-
- /* line 2 */
- d = *data++ ^ doinverse;
- *place = ((d & fg0) | (~d & bg0));
- place[2] = ((d & fg1) | (~d & bg1));
- place += vplanesiz;
-
- /* line 3 */
- d = *data++ ^ doinverse;
- *place = ((d & fg0) | (~d & bg0));
- place[2] = ((d & fg1) | (~d & bg1));
- place += vplanesiz;
-
- /* line 4 */
- d = *data++ ^ doinverse;
- *place = ((d & fg0) | (~d & bg0));
- place[2] = ((d & fg1) | (~d & bg1));
- place += vplanesiz;
-
- /* line 5 */
- d = *data++ ^ doinverse;
- *place = ((d & fg0) | (~d & bg0));
- place[2] = ((d & fg1) | (~d & bg1));
- place += vplanesiz;
-
- /* line 6 */
- d = *data++ ^ doinverse;
- *place = ((d & fg0) | (~d & bg0));
- place[2] = ((d & fg1) | (~d & bg1));
- place += vplanesiz;
-
- /* line 7 */
- d = *data++ ^ doinverse;
- *place = ((d & fg0) | (~d & bg0));
- place[2] = ((d & fg1) | (~d & bg1));
- place += vplanesiz;
-
- /* line 8 */
- d = (*data | dounderline) ^ doinverse;
- *place = ((d & fg0) | (~d & bg0));
- place[2] = ((d & fg1) | (~d & bg1));
- }
- }
-
- static void
- paint816m(v, c, place)
- SCREEN *v;
- int c;
- char *place;
- {
- char *data;
- char d, doinverse, dounderline;
- long vplanesiz;
-
- data = chartab[c];
- doinverse = (v->flags & FINVERSE) ? 0xff : 0;
- doinverse ^= (d = V_BGMASK(v)[0]);
- dounderline = (v->flags & FUNDERLINE) ? 0xff : 0;
- vplanesiz = v->planesiz;
-
- if (d == V_FGMASK(v)[0])
- {
- /* fgcol and bgcol are the same -- easy */
- *place = d;
- place += vplanesiz;
- *place = d;
- place += vplanesiz;
- *place = d;
- place += vplanesiz;
- *place = d;
- place += vplanesiz;
- *place = d;
- place += vplanesiz;
- *place = d;
- place += vplanesiz;
- *place = d;
- place += vplanesiz;
- *place = d;
- if (v->cheight == 8)
- return;
- place += vplanesiz;
- *place = d;
- place += vplanesiz;
- *place = d;
- place += vplanesiz;
- *place = d;
- place += vplanesiz;
- *place = d;
- place += vplanesiz;
- *place = d;
- place += vplanesiz;
- *place = d;
- place += vplanesiz;
- *place = d;
- place += vplanesiz;
- *place = d;
- }
- else if (!doinverse) {
- /* line 1 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 2 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 3 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 4 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 5 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 6 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 7 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 8 */
- d = *data++;
- if (v->cheight == 8) {
- *place = d | dounderline;
- return;
- }
- *place = d;
-
- place += vplanesiz;
-
- /* line 9 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 10 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 11 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 12 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 13 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 14 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 15 */
- d = *data++;
- *place = d;
- place += vplanesiz;
-
- /* line 16 */
- d = *data;
- *place = d | dounderline;
- } else {
- /* line 1 */
- d = ~*data++;
- *place = d;
- place += vplanesiz;
-
- /* line 2 */
- d = ~*data++;
- *place = d;
- place += vplanesiz;
-
- /* line 3 */
- d = ~*data++;
- *place = d;
- place += vplanesiz;
-
- /* line 4 */
- d = ~*data++;
- *place = d;
- place += vplanesiz;
-
- /* line 5 */
- d = ~*data++;
- *place = d;
- place += vplanesiz;
-
- /* line 6 */
- d = ~*data++;
- *place = d;
- place += vplanesiz;
-
- /* line 7 */
- d = ~*data++;
- *place = d;
- place += vplanesiz;
-
- /* line 8 */
- d = ~*data++;
- if (v->cheight == 8) {
- *place = d | dounderline;
- return;
- }
- *place = d;
-
- place += vplanesiz;
-
- /* line 9 */
- d = ~*data++;
- *place = d;
- place += vplanesiz;
-
- /* line 10 */
- d = ~*data++;
- *place = d;
- place += vplanesiz;
-
- /* line 11 */
- d = ~*data++;
- *place = d;
- place += vplanesiz;
-
- /* line 12 */
- d = ~*data++;
- *place = d;
- place += vplanesiz;
-
- /* line 13 */
- d = ~*data++;
- *place = d;
- place += vplanesiz;
-
- /* line 14 */
- d = ~*data++;
- *place = d;
- place += vplanesiz;
-
- /* line 15 */
- d = ~*data++;
- *place = d;
- place += vplanesiz;
-
- /* line 16 */
- d = ~*data;
- *place = d | dounderline;
- }
- }
-
- /*
- * gotoxy (v, x, y): move current cursor address of screen v to (x, y)
- * makes sure that (x, y) will be legal
- */
-
- INLINE static void
- gotoxy(v, x, y)
- SCREEN *v;
- int x, y;
- {
- if (x > v->maxx) x = v->maxx;
- else if (x < 0) x = 0;
- if (y > v->maxy) y = v->maxy;
- else if (y < 0) y = 0;
-
- v->cx = x;
- v->cy = y;
- v->cursaddr = PLACE(v, x, y);
- }
-
- /*
- * clrline(v, r): clear line r of screen v
- */
-
- INLINE static void
- clrline(v, r)
- SCREEN *v;
- int r;
- {
- int *dst, *m;
- long nwords;
- int i, vplanes = v->planes;
-
- /* Hey, again the screen might be bigger than 32767 bytes.
- Do another cast... */
- r += r;
- r += r;
- dst = (int *)(V_LINE(v, r));
- if (v->bgcol == 0)
- zero((char *)dst, v->linelen);
- else if (vplanes == 1)
- memset ((char *)dst, *V_BGMASK(v), v->linelen);
- else
- {
- /* do it the hard way */
- for (nwords = v->linelen >> 1; nwords > 0; nwords -= vplanes)
- {
- m = V_BGMASK(v);
- for (i = 0; i < vplanes; i++)
- *dst++ = *m++;
- }
- }
- }
-
- /*
- * clear(v): clear the whole screen v
- */
-
- INLINE static void
- clear(v)
- SCREEN *v;
- {
- int i, vplanes = v->planes;
- int *dst = (int *) V_BASE(v), *m;
- long nwords;
-
- if (!V_LINEAR_P(v))
- memmove (v->v.t.rowlist, rowoff, ((v->maxy+1) * sizeof(long)));
- if (v->bgcol == 0)
- zero((char *)dst, scrnsize);
- else if (vplanes == 1)
- memset ((char *)dst, *V_BGMASK(v), scrnsize);
- else
- {
- /* do it the hard way */
- for (nwords = scrnsize >> 1; nwords > 0; nwords -= vplanes)
- {
- m = V_BGMASK(v);
- for (i = 0; i < vplanes; i++)
- *dst++ = *m++;
- }
- }
- }
-
- /*
- * clrchars(v, x, y, n): clear n chars starting at position (x,y) on screen v
- */
-
- /*INLINE*/ static void
- clrchars(v, x, y, n)
- SCREEN *v;
- int x, y, n;
- {
- int i, j, vplanes;
- char *place;
- int *m, *l;
-
- if (!x && n == v->maxx+1) {
- clrline(v, y);
- return;
- }
- vplanes = v->planes + v->planes;
-
- if (y == v->cy && x == v->cx)
- place = v->cursaddr;
- else
- place = PLACE(v, x, y);
-
- l = V_BGMASK(v);
- if (vplanes > 2) {
- if (x & 1) {
- char *p = place;
- for (j = v->cheight; j > 0; --j) {
- char *q = p;
- m = l;
- for (i = 0; i < vplanes; i += 2) {
- *q++ = (char) *m++;
- ++q;
- }
- p += v->planesiz;
- }
- place += vplanes-1;
- --n;
- }
- if (n > 1) {
- int nbytes = n*(vplanes>>1);
- char *p = place;
- place += nbytes;
-
- if (v->bgcol == 0) {
- for (j = v->cheight; j > 0; --j) {
- bzero(p, nbytes);
- p += v->planesiz;
- }
- } else {
- for (j = v->cheight; j > 0; --j) {
- short *q = (short *)p;
- int k;
-
- for (k = n; k > 1; k -= 2) {
- m = l;
- for (i = 0; i < vplanes; i += 2)
- *q++ = *m++;
- }
- p += v->planesiz;
- }
- }
- }
- if (n & 1) {
- for (j = v->cheight; j > 0; --j) {
- char *p = place;
- m = l;
- for (i = 0; i < vplanes; i += 2) {
- *p++ = (char) *m++;
- ++p;
- }
- }
- place += v->planesiz;
- }
- } else {
- for (j = v->cheight; j > 0; --j) {
- memset (place, *l, n);
- place += v->planesiz;
- }
- }
- }
-
- /*
- * clrfrom(v, x1, y1, x2, y2): clear screen v from position (x1,y1) to
- * position (x2, y2) inclusive. It is assumed that y2 >= y1.
- */
-
- INLINE static void
- clrfrom(v, x1, y1, x2, y2)
- SCREEN *v;
- int x1,y1,x2,y2;
- {
- int i;
-
- clrchars(v, x1, y1, (y2 == y1 ? x2 : v->maxx)-x1+1);
- if (y2 > y1) {
- for (i = y1+1; i < y2; i++)
- clrline(v, i);
- clrchars(v, 0, y2, x2);
- }
- }
-
- /*
- * scroll a screen in hardware; if we still have hardware scrolling lines left,
- * just move the physical screen base, otherwise copy the screen back to the
- * hardware base and start over
- */
- void
- hardware_scroll(v)
- SCREEN *v;
- {
-
- ++hardline;
- if (hardline < hardscroll) { /* just move the screen */
- v->v.t.vbase += v->linelen;
- } else {
- hardline = 0;
- quickmove(hardbase, v->v.t.vbase + v->linelen, scrnsize - v->linelen);
- v->v.t.vbase = hardbase;
- }
- v->cursaddr = PLACE(v, v->cx, v->cy);
- if (vcurrent)
- Setscreen(-1l, v->v.t.vbase, -1);
- }
-
- /*
- * delete_line(v, r): delete line r of screen v. The screen below this
- * line is scrolled up, and the bottom line is cleared.
- */
-
- #define scroll(v) delete_line(v, 0)
-
- INLINE static void
- delete_line(v, r)
- SCREEN *v;
- int r;
- {
- long *src, *dst, nbytes;
-
- /* if this screen needs not be linear (i.e. its `stored' not shown)
- then just adjust the line offset table...
- */
- if (!V_LINEAR_P(v)) {
- register int i = r + r;
- long t;
- i += i;
- src = (long *)(v->v.t.rowlist+i);
- i = v->maxy - r;
- i += i;
- i += i;
- t = *src;
- memmove (src, src+1, i);
- i = v->maxy + v->maxy;
- i += i;
- *(long *)(v->v.t.rowlist+i) = t;
- clrline(v, v->maxy);
- return;
- }
- if (r == 0) {
- if (v != v00 & hardscroll > 0) {
- hardware_scroll(v);
- clrline(v, v->maxy);
- return;
- }
- nbytes = scrnsize - v->linelen;
- } else {
- register int i = v->maxy - r;
- i += i;
- i += i;
- nbytes = *(long *)(rowoff+i);
- }
-
- /* Sheeze, how many times do we really have to cast...
- Erling.
- */
-
- r += r;
- r += r;
- dst = (long *)(V_BASE(v) + *(long *)(rowoff + r));
- src = (long *)( ((long)dst) + v->linelen);
-
- quickmove(dst, src, nbytes);
-
- /* clear the last line */
- clrline(v, v->maxy);
- }
-
- void
- hardware_scroll_down(v)
- SCREEN *v;
- {
-
- --hardline;
- if (hardline >= 0) { /* just move the screen */
- v->v.t.vbase -= v->linelen;
- } else {
- hardline = hardscroll - 1;
- v->v.t.vbase = hardbase + (long) hardline*v->linelen;
- memmove(v->v.t.vbase + v->linelen, hardbase, scrnsize - v->linelen);
- }
- v->cursaddr = PLACE(v, v->cx, v->cy);
- if (vcurrent)
- Setscreen(-1l, v->v.t.vbase, -1);
- }
-
- /*
- * insert_line(v, r): scroll all of the screen starting at line r down,
- * and then clear line r.
- */
-
- INLINE static void
- insert_line(v, r)
- SCREEN *v;
- int r;
- {
- long *src, *dst;
- int i, j, linelen;
-
- if (!V_LINEAR_P(v)) {
- long t;
- i = r + r;
- i += i;
- src = (long *)(v->v.t.rowlist+i);
- i = v->maxy + v->maxy;
- i += i;
- t = *(long *)(v->v.t.rowlist+i);
- i = v->maxy - r;
- i += i;
- i += i;
- memmove (src+1, src, i);
- *src = t;
- clrline(v, r);
- return;
- }
- if (!r && v != v00 & hardscroll > 0) {
- hardware_scroll_down(v);
- clrline(v, 0);
- return;
- }
- i = v->maxy - 1;
- i += i;
- i += i;
- j = r+r;
- j += j;
- linelen = v->linelen;
- src = (long *)(V_BASE(v) + *(long *)(rowoff + i));
- dst = (long *)((long)src + linelen);
- for (; i >= j ; i -= 4) {
- /* move line i to line i+1 */
- quickmove(dst, src, linelen);
- dst = src;
- src = (long *)((long) src - linelen);
- }
-
- /* clear line r */
- clrline(v, r);
- }
-
- /*
- * special states for handling ESC b x and ESC c x. Note that for now,
- * color is ignored.
- */
-
- static void
- setbgcol(v, c)
- SCREEN *v;
- int c;
- {
- int i;
- int *m = V_BGMASK(v);
-
- v->bgcol = c & ((1 << v->planes)-1);
- for (i = 0; i < v->planes; i++)
- *m++ = (v->bgcol & (1 << i)) ? -1 : 0;
- *V_STATE(v) = normal_putch;
- }
-
- static void
- setfgcol(v, c)
- SCREEN *v;
- int c;
- {
- int i;
- int *m = V_FGMASK(v);
-
- v->fgcol = c & ((1 << v->planes)-1);
- for (i = 0; i < v->planes; i++)
- *m++ = (v->fgcol & (1 << i)) ? -1 : 0;
- *V_STATE(v) = normal_putch;
- }
-
- static void
- setcurs(v, c)
- SCREEN *v;
- int c;
- {
- c -= ' ';
- if (!c) {
- v->flags &= ~CURS_FLASH;
- } else {
- v->flags |= CURS_FLASH;
- v->period = (unsigned char) c;
- }
- *V_STATE(v) = normal_putch;
- }
-
- /* set special effects... FIXME: only inverse and underline do anything */
- static void
- seffect_putch(v, c)
- SCREEN *v;
- int c;
- {
- v->flags |= ((c & 0x10) ? FINVERSE : 0)|((c & 0x8) ? FUNDERLINE : 0);
- *V_STATE(v) = normal_putch;
- }
-
- /* clear special effects */
- static void
- ceffect_putch(v, c)
- SCREEN *v;
- int c;
- {
- v->flags &= ~(((c & 0x10) ? FINVERSE : 0)|((c & 0x8) ? FUNDERLINE : 0));
- *V_STATE(v) = normal_putch;
- }
-
- static void
- quote_putch(v, c)
- SCREEN *v;
- int c;
- {
- (*vpaint)(v, c, v->cursaddr);
- *V_STATE(v) = normal_putch;
- }
-
- /*
- * putesc(v, c): handle the control sequence ESC c
- */
-
- static void
- putesc(v, c)
- SCREEN *v;
- int c;
- {
- int i;
- int cx, cy;
-
- cx = v->cx; cy = v->cy;
-
- switch (c) {
- case 'A': /* cursor up */
- if (cy) {
- moveup: v->cy = --cy;
- if (V_LINEAR_P(v))
- v->cursaddr -= v->linelen;
- else {
- long *r;
- i = cy + cy;
- i += i;
- r = (long *)(v->v.t.rowlist+i);
- v->cursaddr -= r[1] - r[0];
- }
- }
- break;
- case 'B': /* cursor down */
- if (cy < v->maxy) {
- v->cy = ++cy;
- if (V_LINEAR_P(v))
- v->cursaddr += v->linelen;
- else {
- long *r;
- i = cy + cy;
- i += i;
- r = (long *)(v->v.t.rowlist+i);
- v->cursaddr += r[0] - r[-1];
- }
- }
- break;
- case 'C': /* cursor right */
- if (cx < v->maxx) {
- if ((i = v->planes-1) && (cx & 1))
- v->cursaddr += i + i;
- v->cx = ++cx;
- v->cursaddr++;
- }
- break;
- case 'D': /* cursor left */
- if (cx) {
- v->cx = --cx;
- v->cursaddr--;
- if ((i = v->planes-1) && (cx & 1))
- v->cursaddr -= i + i;
- }
- break;
- case 'E': /* clear home */
- clear(v);
- /* fall through... */
- case 'H': /* cursor home */
- v->cx = 0; v->cy = 0;
- v->cursaddr = V_LINE(v, 0);
- break;
- case 'I': /* cursor up, insert line */
- if (cy == 0) {
- insert_line(v, 0);
- if (!V_LINEAR_P(v)) {
- long *r;
- i = cy + cy;
- i += i;
- r = (long *)(v->v.t.rowlist+i);
- v->cursaddr -= r[1] - r[0];
- }
- }
- else
- goto moveup;
- break;
- case 'J': /* clear below cursor */
- clrfrom(v, cx, cy, v->maxx, v->maxy);
- break;
- case 'K': /* clear remainder of line */
- clrfrom(v, cx, cy, v->maxx, cy);
- break;
- case 'L': /* insert a line */
- v->cx = 0;
- i = cy + cy;
- i += i;
- insert_line(v, cy);
- v->cursaddr = V_LINE(v, i);
- break;
- case 'M': /* delete line */
- v->cx = 0;
- i = cy + cy;
- i += i;
- delete_line(v, cy);
- v->cursaddr = V_LINE(v, i);
- break;
- case 'Q': /* EXTENSION: quote-next-char */
- *V_STATE(v) = quote_putch;
- return;
- case 'Y':
- *V_STATE(v) = escy_putch;
- return; /* YES, this should be 'return' */
-
- case 'b':
- *V_STATE(v) = setfgcol;
- return;
- case 'c':
- *V_STATE(v) = setbgcol;
- return;
- case 'd': /* clear to cursor position */
- clrfrom(v, 0, 0, cx, cy);
- break;
- case 'e': /* enable cursor */
- v->flags |= CURS_ON;
- v->hidecnt = 1; /* so --v->hidecnt shows the cursor */
- break;
- case 'f': /* cursor off */
- v->hidecnt++;
- v->flags &= ~CURS_ON;
- break;
- case 'j': /* save cursor position */
- v->savex = v->cx;
- v->savey = v->cy;
- break;
- case 'k': /* restore saved position */
- gotoxy(v, v->savex, v->savey);
- break;
- case 'l': /* clear line */
- v->cx = 0;
- i = cy + cy;
- i += i;
- v->cursaddr = V_LINE(v, i);
- clrline(v, cy);
- break;
- case 'o': /* clear from start of line to cursor */
- clrfrom(v, 0, cy, cx, cy);
- break;
- case 'p': /* reverse video on */
- v->flags |= FINVERSE;
- break;
- case 'q': /* reverse video off */
- v->flags &= ~FINVERSE;
- break;
- case 't': /* EXTENSION: set cursor flash rate */
- *V_STATE(v) = setcurs;
- return;
- case 'v': /* wrap on */
- v->flags |= FWRAP;
- break;
- case 'w':
- v->flags &= ~FWRAP;
- break;
- case 'y': /* EXTENSION: set special effects */
- *V_STATE(v) = seffect_putch;
- curs_on(v);
- return;
- case 'z': /* EXTENSION: clear special effects */
- *V_STATE(v) = ceffect_putch;
- curs_on(v);
- return;
- }
- *V_STATE(v) = normal_putch;
- }
-
- /*
- * escy1_putch(v, c): for when an ESC Y + char has been seen
- */
- static void
- escy1_putch(v, c)
- SCREEN *v;
- int c;
- {
- /* some (un*x) termcaps seem to always set the hi bit on
- cm args (cm=\EY%+ %+ :) -> drop that unless the screen
- is bigger. -nox
- */
- gotoxy(v, (c-' ') & (v->maxx|0x7f), (V_ESCY1(v)-' ') & (v->maxy|0x7f));
- *V_STATE(v) = normal_putch;
- }
-
- /*
- * escy_putch(v, c): for when an ESC Y has been seen
- */
- static void
- escy_putch(v, c)
- SCREEN *v;
- int c;
- {
- V_ESCY1(v) = c;
- *V_STATE(v) = escy1_putch;
- }
-
- /*
- * normal_putch(v, c): put character 'c' on screen 'v'. This is the default
- * for when no escape, etc. is active
- */
-
- static void
- normal_putch(v, c)
- SCREEN *v;
- int c;
- {
- register int i;
-
- /* control characters */
- if (c < ' ') {
- switch (c) {
- case '\r':
- col0: v->cx = 0;
- i = v->cy + v->cy;
- i += i;
- v->cursaddr = V_LINE(v, i);
- return;
- case '\n':
- if (v->cy == v->maxy) {
- scroll(v);
- if (!V_LINEAR_P(v)) {
- long *r;
- i = v->cy + v->cy;
- i += i;
- r = (long *)(v->v.t.rowlist+i);
- v->cursaddr += r[0] - r[-1];
- }
- } else {
- v->cy++;
- if (V_LINEAR_P(v))
- v->cursaddr += v->linelen;
- else {
- long *r;
- i = v->cy + v->cy;
- i += i;
- r = (long *)(v->v.t.rowlist+i);
- v->cursaddr += r[0] - r[-1];
- }
- }
- return;
- case '\b':
- if (v->cx) {
- v->cx--;
- v->cursaddr--;
- if ((i = v->planes-1) && (v->cx & 1))
- v->cursaddr -= i+i;
- }
- return;
- case '\007': /* BELL */
- (void)bconout(CONDEV, 7);
- return;
- case '\033': /* ESC */
- *V_STATE(v) = putesc;
- return;
- case '\t':
- if (v->cx < v->maxx) {
- /* this can't be register for an ANSI compiler */
- union {
- long l;
- short i[2];
- } j;
- j.l = 0;
- j.i[1] = 8 - (v->cx & 7);
- v->cx += j.i[1];
- if (v->cx - v->maxx > 0) {
- j.i[1] = v->cx - v->maxx;
- v->cx = v->maxx;
- }
- v->cursaddr += j.l;
- if ((i = v->planes-1)) {
- if (j.l & 1)
- j.i[1]++;
- do v->cursaddr += j.l;
- while (--i);
- }
- }
- return;
- default:
- return;
- }
- }
-
- (*vpaint)(v, c, v->cursaddr);
- v->cx++;
- if (v->cx > v->maxx) {
- if (v->flags & FWRAP) {
- normal_putch(v, '\n');
- goto col0;
- } else {
- v->cx = v->maxx;
- }
- } else {
- v->cursaddr++;
- if ((i = v->planes-1) && !(v->cx & 1)) /* new word */
- v->cursaddr += i + i;
- }
- }
-
- INLINE static void
- put_ch00(v, c)
- SCREEN *v;
- int c;
- {
- (*v00state)(v, c & 0x00ff);
- }
-
- INLINE static void
- put_ch0x(v, c)
- SCREEN *v;
- int c;
- {
- (*v->v.t.state)(v, c & 0x00ff);
- }
-
- static long ARGS_ON_STACK screen_open P_((FILEPTR *f));
- static long ARGS_ON_STACK screen_read P_((FILEPTR *f, char *buf, long nbytes));
- static long ARGS_ON_STACK screen_write P_((FILEPTR *f, const char *buf, long nbytes));
- static long ARGS_ON_STACK screen_lseek P_((FILEPTR *f, long where, int whence));
- static long ARGS_ON_STACK screen_ioctl P_((FILEPTR *f, int mode, void *buf));
- static long ARGS_ON_STACK screen_close P_((FILEPTR *f, int pid));
- static long ARGS_ON_STACK screen_select P_((FILEPTR *f, long p, int mode));
- static void ARGS_ON_STACK screen_unselect P_((FILEPTR *f, long p, int mode));
-
- static long ARGS_ON_STACK screen_datime P_((FILEPTR *f, short *time, int rwflag));
-
- DEVDRV vcon_device = {
- screen_open, screen_write, screen_read, screen_lseek, screen_ioctl,
- screen_datime, screen_close, screen_select, screen_unselect
- };
-
- static long ARGS_ON_STACK
- screen_open(f)
- FILEPTR *f;
- {
- int fd, vt = f->fc.aux;
- char name[] = "u:\\pipe\\q$vt00";
-
- if (!rowoff) {
- init();
- } else if (!ttys[0].use_cnt || leaving)
- /* if we're init'ed already and vt00 is closed that means
- we're uninistalling... */
- return -EACCESS;
- if (!((struct tty *)f->devinfo)->use_cnt) {
- SCREEN *v = VT_SCREEN(vt);
-
- /* init and alloc screen memory if necessary */
- if (vt) {
- if (!v->v.t.vbase) {
- char *vbase = (char *)kmalloc(scrnsize);
- if (!vbase)
- return -ENOMEM;
- init_screen (v, vbase, v->v.t.rowlist, 0);
- } else if (v->v.t.on == V_FREE)
- v->v.t.on = V_USED;
- }
- /* is there a better way??? */
- name[sizeof "u:\\pipe\\q$vt0"-1] = vt+'0';
- if ((fd = FOPEN (name, O_RDONLY|O_GLOBAL)) < 0)
- return fd;
- qfd[vt] = fd;
- q_fl[vt] = 0;
- }
-
- f->flags |= O_TTY;
- return 0;
- }
-
- static long ARGS_ON_STACK
- screen_close(f, pid)
- FILEPTR *f;
- int pid;
- {
- UNUSED(pid);
-
- if (!((struct tty *)f->devinfo)->use_cnt) {
- int vt = f->fc.aux;
-
- /* close pipe */
- FCLOSE (qfd[vt]);
-
- /* last close on vt00 means uninstall... */
- if (!vt)
- deinit();
- /* otherwise it means free screen memory */
- else {
- SCREEN *v = VT_SCREEN(vt);
-
- if (v->v.t.on)
- v->v.t.on = V_FREE;
- else {
- kfree (v->v.t.vbase);
- v->v.t.vbase = 0;
- }
- }
- }
- return 0;
- }
-
- static long ARGS_ON_STACK
- screen_write(f, buf, bytes)
- FILEPTR *f; const char *buf; long bytes;
- {
- int vt = f->fc.aux;
- SCREEN *v = VT_SCREEN(vt);
- long *r;
- long ret = 0;
- int c;
- long tick;
-
- UNUSED(f);
-
- /* tty_write is calling us with no more than one line or 128
- chars at a time but still never(?) allows task-switches
- while doing a longer write... checkkeys() does this when
- it detects a keyboard interrupt but we cant call that.
- instead we look for 0->1 (_hz_200 & 3) ticks that happened
- while we were writing (there are 50 of them in a second)
- and yield() when found one. (comments?)
- */
- #if 0
- (void)checkkeys();
- #else
- tick = _hz_200;
- #endif
- v->hidecnt++;
- v->flags |= CURS_UPD; /* for TOS 1.0 */
- curs_off(v);
- r = (long *)buf;
- if (vt) {
- while (bytes > 0) {
- c = (int) *r++;
- put_ch0x(v, c);
- bytes -= 4; ret+= 4;
- }
- } else {
- while (bytes > 0) {
- c = (int) *r++;
- put_ch00(v, c);
- bytes -= 4; ret+= 4;
- }
- }
- if (v->hidecnt > 0)
- --v->hidecnt;
- else
- v->hidecnt = 0;
- curs_on(v);
- v->flags &= ~CURS_UPD;
- #if 1
- if (tick != _hz_200 && !(tick & 3))
- yield();
- #endif
- return ret;
- }
-
- static long ARGS_ON_STACK
- screen_read(f, buf, bytes)
- FILEPTR *f; char *buf; long bytes;
- {
- int vt = f->fc.aux;
-
- if ((f->flags & O_NDELAY) != q_fl[vt])
- FCNTL (qfd[vt], (long)(q_fl[vt] = f->flags&O_NDELAY), F_SETFL);
- return FREAD (qfd[vt], bytes, buf);
- }
-
- static long ARGS_ON_STACK
- screen_lseek(f, where, whence)
- FILEPTR *f;
- long where;
- int whence;
- {
- /* terminals always are at position 0 */
- UNUSED(f); UNUSED(where);
- UNUSED(whence);
- return 0;
- }
-
- static long ARGS_ON_STACK
- screen_ioctl(f, mode, buf)
- FILEPTR *f; int mode; void *buf;
- {
- int vt = f->fc.aux;
- long *r = (long *)buf;
- struct winsize *w;
-
- UNUSED(f);
-
- if (mode == FIONREAD) {
- *r = FINSTAT (qfd[vt]);
- if (*r > 0)
- *r >>= 2;
- }
- else if (mode == FIONWRITE) {
- *r = 0x400;
- }
- else if (mode == TIOCFLUSH) {
- return FCNTL (qfd[vt], r, TIOCFLUSH);
- }
- else if (mode == TIOCGWINSZ) {
- SCREEN *v = VT_SCREEN(vt);
- w = (struct winsize *)buf;
- w->ws_row = v->maxy+1;
- w->ws_col = v->maxx+1;
- }
- else if (mode >= TCURSOFF && mode <= TCURSGRATE) {
- SCREEN *v = VT_SCREEN(vt);
- switch(mode) {
- case TCURSOFF:
- curs_off(v);
- v->hidecnt++;
- v->flags &= ~CURS_ON;
- break;
- case TCURSON:
- v->flags |= CURS_ON;
- v->hidecnt = 0;
- curs_on(v);
- break;
- case TCURSBLINK:
- curs_off(v);
- v->flags |= CURS_FLASH;
- curs_on(v);
- break;
- case TCURSSTEADY:
- curs_off(v);
- v->flags &= ~CURS_FLASH;
- curs_on(v);
- break;
- case TCURSSRATE:
- v->period = *((short *)buf);
- break;
- case TCURSGRATE:
- return v->period;
- }
- } else
- return -EINVAL;
-
- return 0;
- }
-
- static long ARGS_ON_STACK
- screen_select(f, p, mode)
- FILEPTR *f; long p; int mode;
- {
- struct tty *tty = (struct tty *)f->devinfo;
- int vt = f->fc.aux;
-
- if (mode == O_RDONLY) {
- if (FINSTAT (qfd[vt])) {
- return 1;
- }
- if (tty) {
- /* avoid collisions with other processes */
- if (!tty->rsel)
- tty->rsel = p;
- }
- return 0;
- } else if (mode == O_WRONLY) {
- return 1;
- }
- /* default -- we don't know this mode, return 0 */
- return 0;
- }
-
- static void ARGS_ON_STACK
- screen_unselect(f, p, mode)
- FILEPTR *f;
- long p;
- int mode;
- {
- struct tty *tty = (struct tty *)f->devinfo;
-
- if (tty) {
- if (mode == O_RDONLY && tty->rsel == p)
- tty->rsel = 0;
- else if (mode == O_WRONLY && tty->wsel == p)
- tty->wsel = 0;
- }
- }
-
- long ARGS_ON_STACK
- screen_datime(f, timeptr, rwflag)
- FILEPTR *f;
- short *timeptr;
- int rwflag;
- {
- int vt = f->fc.aux;
-
- if (rwflag)
- return -EACCESS;
- return FDATIME (timeptr, qfd[vt], 0);
- }
- SHAR_EOF
- cat << \SHAR_EOF > vcon.h
- #if 1
-
- #ifdef __GNUC__
- #define EXITING volatile /* function never returns */
- #else
- #define EXITING
- #endif
-
- /* define how to call functions with stack parameter passing */
- #ifdef __TURBOC__
- #define ARGS_ON_STACK cdecl
- #else
- #define ARGS_ON_STACK
- #endif
-
- /* define to indicate unused variables */
- #ifdef __TURBOC__
- #define UNUSED(x) (void)x
- #else
- #define UNUSED(x)
- #endif
-
- #ifdef __STDC__
- #define P_(x) x
- #else
- #define P_(x) ()
- #define const
- #define volatile
- #endif
-
- typedef unsigned short ushort;
- typedef long ARGS_ON_STACK (*Func)();
- #include "file.h"
- #else
- #include "filesys.h"
- #endif
-
- #define CTRL(x) ((x) & 0x1f)
- #ifndef T_NOFLSH
- #define T_NOFLSH 0x0040 /* don't flush buffer when signals
- are received */
- #endif
-
- #if !RAW
- #undef RAW
- #undef ECHO
- #define RAW T_RAW
- #define ECHO T_ECHO
- #define CRMOD T_CRMOD
- #define CBREAK T_CBREAK
- #define TOSTOP T_TOSTOP
- #define XKEY T_XKEY
- #endif
-
- extern struct kerinfo *kernel;
- #define CCONWS (void)(*kernel->dos_tab[0x09])
-
- #define FOPEN (*kernel->dos_tab[0x3d])
- #define FCLOSE (*kernel->dos_tab[0x3e])
- #define FREAD (*kernel->dos_tab[0x3f])
- #define MXALLOC (*kernel->dos_tab[0x44])
- #define FDATIME (*kernel->dos_tab[0x44])
- #define FCNTL (*kernel->dos_tab[0x104])
- #define FINSTAT (*kernel->dos_tab[0x105])
- #define FGETCHAR (*kernel->dos_tab[0x107])
-
- #define SPRINTF (*kernel->sprintf)
- #define DEBUG (*kernel->debug)
- #define ALERT (*kernel->alert)
- #define TRACE (*kernel->trace)
- #define FATAL (*kernel->fatal)
- #define KMALLOC (*kernel->kmalloc)
- #define KFREE (*kernel->kfree)
- #define SLEEP (*kernel->sleep)
- #define WAKESELECT (*kernel->wakeselect)
-
- SHAR_EOF
- cat << \SHAR_EOF > vtdev.h
- /* should be equivalent... atleast for mintlib. */
- #include <string.h>
- #define quickmove memmove
- #define zero bzero
- /* only possible because main open()s /dev/vt00 that calls this. */
- #define kcore(x) MXALLOC((long)(x),0)
- /* should this do something? */
- #define checkkeys() (0)
- #define kmalloc KMALLOC
- #define kfree KFREE
- #define bconout Bconout
- #define yield() SLEEP(1, 0l)
-
- /* number of terminals (max) */
- #define N_VT 10
-
- #define MAX_PLANES 8
-
- #define ALT_1 0x780000L
- #define ALT_2 0x790000L
- #define ALT_0 0x810000L
-
- struct screen;
-
- typedef void (*Vfunc) P_((struct screen *, int));
-
- typedef struct screen {
- short hidecnt; /* cursor hide count */
- short mcurx, mcury; /* current mouse X, Y position */
- char mdraw;
- char mouseflag;
- long junk1;
- short savex, savey; /* saved X, Y position */
- short msavelen; /* mouse save stuff */
- long msaveaddr;
- short msavestat;
- union {
- long msavearea[64];
- /* additional stuff, NOT for vt00! */
- struct {
- Vfunc state;
- short vescy1;
- int fgmask[MAX_PLANES];
- int bgmask[MAX_PLANES];
- char *vbase; /* screens address */
- char *rowlist; /* pointer to line offsets */
- short on; /* 0 if screen `stored'... */
- #define V_USED 1 /* not stored, open */
- #define V_FREE 2 /* not stored, closed, free screen memory later */
- } t;
- } v;
- long user_tim, next_tim; /* time vector stuff */
- long user_but, user_cur,
- user_mot; /* more user vectors */
- short cheight; /* character height */
- short maxx; /* number of characters across - 1 */
- short maxy; /* number of characters high - 1 */
- short linelen; /* length (in bytes) of a line of characters */
- short bgcol; /* background color */
- short fgcol; /* foreground color */
- char *cursaddr; /* cursor address */
- short v_cur_of; /* ??? */
- short cx, cy; /* current (x,y) position of cursor */
- char period; /* cursor flash period (in frames) */
- char curstimer; /* cursor flash timer */
- char *fontdata; /* pointer to font data */
- short firstcode; /* first ASCII code in font */
- short lastcode; /* last ASCII code in font */
- short form_width; /* # bytes/scanline in font data */
- short xpixel;
- char *fontoff; /* pointer to font offset table */
- char flags; /* e.g. cursor on/off */
- char reserved;
- short ypixel;
- short width; /* length of a screen scan line */
- short planes; /* number of planes on screen */
- short planesiz; /* length of a screen scan line */
- } SCREEN;
-
- #define SCNSIZE(v) ( (((long)v->maxy + hardscroll + 2)) * v->linelen )
-
- /* possible flags for cursor state, etc. */
- #define CURS_FLASH 0x01 /* cursor flashing */
- #define CURS_FSTATE 0x02 /* cursor in flash state */
- #define CURS_ON 0x04 /* cursor on */
- #define FWRAP 0x08 /* wrap cursor at end of line */
- #define FINVERSE 0x10 /* invert text */
- #define FUNDERLINE 0x20 /* EXTENSION: underline text */
- #define CURS_UPD 0x40 /* cursor update flag */
-
- extern DEVDRV vcon_device;
- extern struct tty ttys[];
- extern struct dev_descr devinfo[];
- extern int vcurrent;
- extern short hardscroll, leaving;
- extern SCREEN *v00, v0x[], *current;
- int setcurrent();
- SHAR_EOF
- cat << \SHAR_EOF > Makefile
- # Makefile for vcon; nothing special...
-
- CC = gcc
- CFLAGS = -g -mshort -O2 -Wall
- LDFLAGS = -g -mshort
-
- vcon: vcon.o vtdev.o
- $(CC) -G $(LDFLAGS) vcon.o vtdev.o -ovcon
- @echo done.
-
- vcon.sym: vcon.o vtdev.o
- $(CC) -B/usr/lib/sym- $(LDFLAGS) vcon.o vtdev.o -ovcon.sym
- @echo done.
-
- SHAR_EOF
- # End of shell archive
- exit 0
- --
- J"urgen Lock / nox@jelal.north.de / UUCP: ..!uunet!unido!uniol!jelal!nox
- ...ohne Gewehr
- PGP public key fingerprint = 8A 18 58 54 03 7B FC 12 1F 8B 63 C7 19 27 CF DA
-